package org.zjvis.datascience.service;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.zjvis.datascience.common.dto.FolderDTO;
import org.zjvis.datascience.common.dto.MLModelDTO;
import org.zjvis.datascience.common.enums.ModelStatusEnum;
import org.zjvis.datascience.common.model.TaskMeta;
import org.zjvis.datascience.common.util.JwtUtil;
import org.zjvis.datascience.common.vo.FolderVO;
import org.zjvis.datascience.common.vo.MLModelVO;
import org.zjvis.datascience.service.mapper.FolderMapper;
import org.zjvis.datascience.service.mapper.MLModelMapper;

import java.util.ArrayList;
import java.util.List;

/**
 * @description Folder 文件夹 Service
 * @date 2021-09-29
 */
@Service
public class FolderService {

    private boolean isContainKey(String name, String searchKey) {
        String lowerName = name.toLowerCase();
        String lowerKey = searchKey.toLowerCase();
        return lowerName.contains(lowerKey);
    }

    protected final static Logger logger = LoggerFactory.getLogger("MLModelService");

    @Autowired
    private FolderMapper folderMapper;

    @Autowired
    private MinioService minioService;

    @Autowired
    private MLModelService mlModelService;

    @Autowired
    private MLModelMapper mlModelMapper;

    public static String MLMODEL_BUCKET = "ml-model";

    public Long createFolder(FolderDTO folder) {
        List<FolderDTO> currentFolders = folderMapper.queryFolderByUser(folder);
        if (currentFolders.size() >= 10) {
            return -2L;
        }
        for (FolderDTO cFolder : currentFolders) {
            if (cFolder.getName().equals(folder.getName())) {
                return -1L;
            }
        }
        folderMapper.save(folder);
        return folder.getId();
    }

    public void updateFolder(FolderDTO dto) {
        folderMapper.updateFolder(dto);
    }

    public List<MLModelDTO> queryFolder(FolderVO vo) {
        return folderMapper.queryFolder(vo);
    }

    public List<FolderDTO> getFolders(MLModelVO vo) {
        return folderMapper.getFolders(vo);
    }

    public FolderDTO getFolderById(MLModelVO vo) {
        return folderMapper.getFolderById(vo);
    }

    public void deleteModel(MLModelDTO model) {
        if (model.getInvisible().equals(ModelStatusEnum.DELETED_IN_FIELD.getVal())) {
            String minioModelPath = model.getModelPath();
            if (minioModelPath != null) {
                if (isContainKey(minioModelPath, "spark")) {
                    String modelpath = model.getModelPath().split("ml-model/")[1];

                    String prefixData = modelpath + "/data";
                    String prefixMetaData = modelpath + "/metadata";
                    List<String> dataobjectNames = null;
                    try {
                        dataobjectNames = minioService.listObjects(MLMODEL_BUCKET, prefixData);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    List<String> metaobjectNames = null;
                    try {
                        metaobjectNames = minioService.listObjects(MLMODEL_BUCKET, prefixMetaData);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }

                    List<String> objectNames = new ArrayList<>();

                    for (String objectName : dataobjectNames) {
                        objectNames.add(prefixData + objectName);
                    }

                    for (String objectName : metaobjectNames) {
                        objectNames.add(prefixMetaData + objectName);
                    }
                    try {
                        minioService.deleteObjects(MLMODEL_BUCKET, objectNames);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                } else {
                    try {
                        minioService.deleteObject(MLMODEL_BUCKET, minioModelPath.split("ml-model/")[1]);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
            mlModelService.delete(model.getId());
        }
    }


    public Long deleteFolder(FolderDTO dto, Long pipelineId) {
        List<MLModelDTO> models = mlModelMapper.queryByFolder(dto);
        //这里get的sourceId是invisible，如果是1则删除模型全部信息
        if (null != pipelineId) {
            for (MLModelDTO model : models) {
                Long authRes = mlModelService.modelDelAuth(model.getId(), pipelineId);
                if (authRes != 0L) {
                    return authRes;
                }
            }
        }
        folderMapper.deleteFolder(dto);
        for (MLModelDTO model : models) {
            deleteModel(model);
        }
        mlModelMapper.removeFolderRecord(dto);
        return 0L;
    }

    public void deleteModelInFolder(MLModelDTO model) {
        MLModelDTO modelDTO = mlModelMapper.queryMetricsById(model.getId());
        deleteModel(modelDTO);
        mlModelMapper.removeModelRecord(modelDTO);
    }

    public List<MLModelVO> queryModelByFolderId(Long folderId) {
        return folderMapper.queryModelByFolderId(folderId);
    }

    public FolderDTO copyIntoNewProject(TaskMeta meta, Long projectId) {
        FolderDTO folder = folderMapper.queryById(meta.getId());
        folder.setId(null);
        folder.setUserId(JwtUtil.getCurrentUserId());
        folder.setProjectId(projectId);
        folderMapper.save(folder);
        return folder;
    }
}
